package com.funsport.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.funsport.entity.*;
import com.funsport.service.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Statistics Service实现
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class StatisticsServiceImpl implements IStatisticsService {

    private final IUserService userService;
    private final IClubService clubService;
    private final IEventService eventService;
    private final IEventSignupService eventSignupService;
    private final IVenueService venueService;
    private final IClubMemberService clubMemberService;

    @Override
    public Map<String, Object> getPlatformStatistics() {
        Map<String, Object> stats = new HashMap<>();

        // 用户总数
        long totalUsers = userService.count();
        stats.put("totalUsers", totalUsers);

        // 俱乐部总数
        long totalClubs = clubService.count();
        stats.put("totalClubs", totalClubs);

        // 活动总数
        long totalEvents = eventService.count();
        stats.put("totalEvents", totalEvents);

        // 场地总数
        long totalVenues = venueService.count();
        stats.put("totalVenues", totalVenues);

        // 今日新增用户
        LocalDateTime todayStart = LocalDateTime.of(LocalDate.now(), LocalTime.MIN);
        long todayNewUsers = userService.count(new LambdaQueryWrapper<User>()
                .ge(User::getCreatedAt, todayStart));
        stats.put("todayNewUsers", todayNewUsers);

        // 本周活动数
        LocalDateTime weekStart = LocalDateTime.now().minusDays(7);
        long weekEvents = eventService.count(new LambdaQueryWrapper<Event>()
                .ge(Event::getCreatedAt, weekStart));
        stats.put("weekEvents", weekEvents);

        // 活跃用户数（最近30天有活动的用户）
        LocalDateTime monthStart = LocalDateTime.now().minusDays(30);
        List<EventSignup> recentSignups = eventSignupService.list(new LambdaQueryWrapper<EventSignup>()
                .ge(EventSignup::getCreatedAt, monthStart));
        long activeUsers = recentSignups.stream()
                .map(EventSignup::getUserId)
                .distinct()
                .count();
        stats.put("activeUsers", activeUsers);

        log.info("平台总体统计: {}", stats);
        return stats;
    }

    @Override
    public Map<String, Object> getUserStatistics(LocalDate startDate, LocalDate endDate) {
        Map<String, Object> stats = new HashMap<>();

        LocalDateTime startDateTime = startDate.atStartOfDay();
        LocalDateTime endDateTime = endDate.atTime(LocalTime.MAX);

        // 新增用户数
        long newUsers = userService.count(new LambdaQueryWrapper<User>()
                .between(User::getCreatedAt, startDateTime, endDateTime));
        stats.put("newUsers", newUsers);

        // 按角色分类
        Map<String, Long> usersByRole = new HashMap<>();
        List<User> users = userService.list();
        usersByRole.put("user", users.stream().filter(u -> "user".equals(u.getRole())).count());
        usersByRole.put("club_admin", users.stream().filter(u -> "club_admin".equals(u.getRole())).count());
        usersByRole.put("venue_manager", users.stream().filter(u -> "venue_manager".equals(u.getRole())).count());
        usersByRole.put("admin", users.stream().filter(u -> "admin".equals(u.getRole())).count());
        stats.put("usersByRole", usersByRole);

        // 按等级分布
        Map<String, Long> usersByLevel = users.stream()
                .collect(Collectors.groupingBy(
                        u -> "Level " + u.getLevel(),
                        Collectors.counting()
                ));
        stats.put("usersByLevel", usersByLevel);

        // 平均积分
        double avgPoints = users.stream()
                .mapToInt(User::getPoints)
                .average()
                .orElse(0.0);
        stats.put("avgPoints", avgPoints);

        log.info("用户统计: startDate={}, endDate={}, newUsers={}", startDate, endDate, newUsers);
        return stats;
    }

    @Override
    public Map<String, Object> getClubStatistics(Long clubId, LocalDate startDate, LocalDate endDate) {
        Map<String, Object> stats = new HashMap<>();

        LocalDateTime startDateTime = startDate.atStartOfDay();
        LocalDateTime endDateTime = endDate.atTime(LocalTime.MAX);

        if (clubId != null) {
            // 单个俱乐部统计
            Club club = clubService.getById(clubId);
            if (club != null) {
                stats.put("clubName", club.getName());
                stats.put("memberCount", club.getCurrentMembers());
                stats.put("points", club.getPoints());
                stats.put("level", club.getLevel());

                // 活动数量
                long eventCount = eventService.count(new LambdaQueryWrapper<Event>()
                        .eq(Event::getClubId, clubId)
                        .between(Event::getCreatedAt, startDateTime, endDateTime));
                stats.put("eventCount", eventCount);

                // 成员活跃度
                List<ClubMember> members = clubMemberService.getClubMembers(clubId, "active");
                double avgContribution = members.stream()
                        .mapToInt(ClubMember::getContributionPoints)
                        .average()
                        .orElse(0.0);
                stats.put("avgMemberContribution", avgContribution);
            }
        } else {
            // 所有俱乐部统计
            long totalClubs = clubService.count();
            stats.put("totalClubs", totalClubs);

            // 新增俱乐部
            long newClubs = clubService.count(new LambdaQueryWrapper<Club>()
                    .between(Club::getCreatedAt, startDateTime, endDateTime));
            stats.put("newClubs", newClubs);

            // 平均成员数
            List<Club> clubs = clubService.list();
            double avgMembers = clubs.stream()
                    .mapToInt(Club::getCurrentMembers)
                    .average()
                    .orElse(0.0);
            stats.put("avgMembers", avgMembers);

            // 总活动点数
            int totalPoints = clubs.stream()
                    .mapToInt(Club::getPoints)
                    .sum();
            stats.put("totalPoints", totalPoints);
        }

        log.info("俱乐部统计: clubId={}, startDate={}, endDate={}", clubId, startDate, endDate);
        return stats;
    }

    @Override
    public Map<String, Object> getEventStatistics(LocalDate startDate, LocalDate endDate) {
        Map<String, Object> stats = new HashMap<>();

        LocalDateTime startDateTime = startDate.atStartOfDay();
        LocalDateTime endDateTime = endDate.atTime(LocalTime.MAX);

        // 总活动数
        long totalEvents = eventService.count(new LambdaQueryWrapper<Event>()
                .between(Event::getCreatedAt, startDateTime, endDateTime));
        stats.put("totalEvents", totalEvents);

        // 按状态分类
        List<Event> events = eventService.list(new LambdaQueryWrapper<Event>()
                .between(Event::getCreatedAt, startDateTime, endDateTime));
        
        Map<String, Long> eventsByStatus = events.stream()
                .collect(Collectors.groupingBy(
                        e -> e.getStatus().name(),
                        Collectors.counting()
                ));
        stats.put("eventsByStatus", eventsByStatus);

        // 平均参与人数
        double avgParticipants = events.stream()
                .mapToInt(Event::getCurrentParticipants)
                .average()
                .orElse(0.0);
        stats.put("avgParticipants", avgParticipants);

        // 平均报名率
        double avgSignupRate = events.stream()
                .filter(e -> e.getMaxParticipants() > 0)
                .mapToDouble(e -> (double) e.getCurrentParticipants() / e.getMaxParticipants() * 100)
                .average()
                .orElse(0.0);
        stats.put("avgSignupRate", avgSignupRate);

        // 总签到人数
        long totalCheckIns = eventSignupService.count(new LambdaQueryWrapper<EventSignup>()
                .eq(EventSignup::getCheckedIn, true)
                .between(EventSignup::getCreatedAt, startDateTime, endDateTime));
        stats.put("totalCheckIns", totalCheckIns);

        // 签到率
        long totalSignups = eventSignupService.count(new LambdaQueryWrapper<EventSignup>()
                .eq(EventSignup::getStatus, "confirmed")
                .between(EventSignup::getCreatedAt, startDateTime, endDateTime));
        double checkInRate = totalSignups > 0 ? (double) totalCheckIns / totalSignups * 100 : 0;
        stats.put("checkInRate", checkInRate);

        log.info("活动统计: startDate={}, endDate={}, totalEvents={}", startDate, endDate, totalEvents);
        return stats;
    }

    @Override
    public Map<String, Object> getVenueStatistics(Long venueId, LocalDate startDate, LocalDate endDate) {
        Map<String, Object> stats = new HashMap<>();

        LocalDateTime startDateTime = startDate.atStartOfDay();
        LocalDateTime endDateTime = endDate.atTime(LocalTime.MAX);

        if (venueId != null) {
            // 单个场地统计
            Venue venue = venueService.getById(venueId);
            if (venue != null) {
                stats.put("venueName", venue.getName());
                stats.put("city", venue.getCity());
                stats.put("address", venue.getAddress());

                // 使用该场地的活动数
                long eventCount = eventService.count(new LambdaQueryWrapper<Event>()
                        .eq(Event::getVenueId, venueId)
                        .between(Event::getStartTime, startDateTime, endDateTime));
                stats.put("eventCount", eventCount);
            }
        } else {
            // 所有场地统计
            long totalVenues = venueService.count();
            stats.put("totalVenues", totalVenues);

            // 按状态分类
            List<Venue> venues = venueService.list();
            Map<String, Long> venuesByStatus = venues.stream()
                    .collect(Collectors.groupingBy(
                            Venue::getStatus,
                            Collectors.counting()
                    ));
            stats.put("venuesByStatus", venuesByStatus);

            // 按城市分类
            Map<String, Long> venuesByCity = venues.stream()
                    .filter(v -> v.getCity() != null)
                    .collect(Collectors.groupingBy(
                            Venue::getCity,
                            Collectors.counting()
                    ));
            stats.put("venuesByCity", venuesByCity);
        }

        log.info("场地统计: venueId={}, startDate={}, endDate={}", venueId, startDate, endDate);
        return stats;
    }

    @Override
    public Map<String, Object> getUserActivityStatistics(Integer days) {
        Map<String, Object> stats = new HashMap<>();
        LocalDateTime startTime = LocalDateTime.now().minusDays(days);

        // 活跃用户数（有登录或活动记录的用户）
        List<EventSignup> signups = eventSignupService.list(new LambdaQueryWrapper<EventSignup>()
                .ge(EventSignup::getCreatedAt, startTime));
        
        long activeUsers = signups.stream()
                .map(EventSignup::getUserId)
                .distinct()
                .count();
        stats.put("activeUsers", activeUsers);

        // 每日活跃用户趋势（简化版）
        Map<LocalDate, Long> dailyActiveUsers = signups.stream()
                .collect(Collectors.groupingBy(
                        s -> s.getCreatedAt().toLocalDate(),
                        Collectors.mapping(EventSignup::getUserId, Collectors.toSet())
                ))
                .entrySet().stream()
                .collect(Collectors.toMap(
                        Map.Entry::getKey,
                        e -> (long) e.getValue().size()
                ));
        stats.put("dailyActiveUsers", dailyActiveUsers);

        // 用户留存率（简化计算）
        long totalUsers = userService.count();
        double retentionRate = totalUsers > 0 ? (double) activeUsers / totalUsers * 100 : 0;
        stats.put("retentionRate", retentionRate);

        log.info("用户活跃度统计: days={}, activeUsers={}", days, activeUsers);
        return stats;
    }

    @Override
    public Map<String, Object> getSportTypePopularity(Integer days) {
        Map<String, Object> stats = new HashMap<>();
        LocalDateTime startTime = LocalDateTime.now().minusDays(days);

        List<Event> recentEvents = eventService.list(new LambdaQueryWrapper<Event>()
                .ge(Event::getCreatedAt, startTime));

        // 按运动类型统计活动数
        Map<Integer, Long> eventsBySportType = recentEvents.stream()
                .filter(e -> e.getSportTypeId() != null)
                .collect(Collectors.groupingBy(
                        Event::getSportTypeId,
                        Collectors.counting()
                ));
        stats.put("eventsBySportType", eventsBySportType);

        // 按运动类型统计参与人数
        Map<Integer, Integer> participantsBySportType = recentEvents.stream()
                .filter(e -> e.getSportTypeId() != null)
                .collect(Collectors.groupingBy(
                        Event::getSportTypeId,
                        Collectors.summingInt(Event::getCurrentParticipants)
                ));
        stats.put("participantsBySportType", participantsBySportType);

        log.info("运动类型热度统计: days={}", days);
        return stats;
    }

    @Override
    public Map<String, Object> getCityDistribution(Integer days) {
        Map<String, Object> stats = new HashMap<>();
        LocalDateTime startTime = LocalDateTime.now().minusDays(days);

        List<Event> recentEvents = eventService.list(new LambdaQueryWrapper<Event>()
                .ge(Event::getCreatedAt, startTime));

        // Event实体没有city字段，暂时不统计城市分布
        // Map<String, Long> eventsByCity = ...
        Map<String, Long> eventsByCity = new HashMap<>();
        stats.put("eventsByCity", eventsByCity);

        // 按城市统计用户数
        List<User> users = userService.list();
        Map<String, Long> usersByCity = users.stream()
                .filter(u -> u.getCity() != null)
                .collect(Collectors.groupingBy(
                        User::getCity,
                        Collectors.counting()
                ));
        stats.put("usersByCity", usersByCity);

        log.info("城市活动分布统计: days={}", days);
        return stats;
    }

    @Override
    public Map<String, Object> getClubRankings(String type, Integer limit) {
        Map<String, Object> rankings = new HashMap<>();
        List<Club> clubs = clubService.list();

        List<Map<String, Object>> rankedClubs = new ArrayList<>();

        switch (type) {
            case "members":
                // 按成员数排名
                clubs.sort(Comparator.comparing(Club::getCurrentMembers).reversed());
                break;
            case "events":
                // 按活动数排名（需要统计）
                for (Club club : clubs) {
                    long eventCount = eventService.count(new LambdaQueryWrapper<Event>()
                            .eq(Event::getClubId, club.getId()));
                    Map<String, Object> clubData = new HashMap<>();
                    clubData.put("club", club);
                    clubData.put("eventCount", eventCount);
                    rankedClubs.add(clubData);
                }
                rankedClubs.sort((a, b) -> 
                        Long.compare((Long) b.get("eventCount"), (Long) a.get("eventCount")));
                rankings.put("rankings", rankedClubs.stream().limit(limit).collect(Collectors.toList()));
                return rankings;
            case "activity":
            default:
                // 按活跃度积分排名
                clubs.sort(Comparator.comparing(Club::getPoints).reversed());
                break;
        }

        rankings.put("rankings", clubs.stream()
                .limit(limit)
                .map(club -> {
                    Map<String, Object> clubData = new HashMap<>();
                    clubData.put("club", club);
                    return clubData;
                })
                .collect(Collectors.toList()));

        log.info("俱乐部排行榜: type={}, limit={}", type, limit);
        return rankings;
    }

    @Override
    public Map<String, Object> getUserRankings(String type, Integer limit) {
        Map<String, Object> rankings = new HashMap<>();
        List<User> users = userService.list();

        List<Map<String, Object>> rankedUsers = new ArrayList<>();

        switch (type) {
            case "points":
                // 按积分排名
                users.sort(Comparator.comparing(User::getPoints).reversed());
                break;
            case "events":
                // 按参与活动数排名
                for (User user : users) {
                    long eventCount = eventSignupService.count(new LambdaQueryWrapper<EventSignup>()
                            .eq(EventSignup::getUserId, user.getId())
                            .eq(EventSignup::getStatus, "attended"));
                    Map<String, Object> userData = new HashMap<>();
                    userData.put("user", user);
                    userData.put("eventCount", eventCount);
                    rankedUsers.add(userData);
                }
                rankedUsers.sort((a, b) -> 
                        Long.compare((Long) b.get("eventCount"), (Long) a.get("eventCount")));
                rankings.put("rankings", rankedUsers.stream().limit(limit).collect(Collectors.toList()));
                return rankings;
            case "contributions":
                // 按贡献度排名（参加的俱乐部活动）
                for (User user : users) {
                    List<ClubMember> memberships = clubMemberService.list(new LambdaQueryWrapper<ClubMember>()
                            .eq(ClubMember::getUserId, user.getId()));
                    int totalContribution = memberships.stream()
                            .mapToInt(ClubMember::getContributionPoints)
                            .sum();
                    Map<String, Object> userData = new HashMap<>();
                    userData.put("user", user);
                    userData.put("totalContribution", totalContribution);
                    rankedUsers.add(userData);
                }
                rankedUsers.sort((a, b) -> 
                        Integer.compare((Integer) b.get("totalContribution"), (Integer) a.get("totalContribution")));
                rankings.put("rankings", rankedUsers.stream().limit(limit).collect(Collectors.toList()));
                return rankings;
            default:
                users.sort(Comparator.comparing(User::getPoints).reversed());
                break;
        }

        rankings.put("rankings", users.stream()
                .limit(limit)
                .map(user -> {
                    Map<String, Object> userData = new HashMap<>();
                    userData.put("user", user);
                    return userData;
                })
                .collect(Collectors.toList()));

        log.info("用户排行榜: type={}, limit={}", type, limit);
        return rankings;
    }
}

